
import DebugExt from "../NRLib/base/DebugExt";
import CanvasExt from "../NRLib/ccExt/CanvasExt";
import PublicUIBase from "./IPublicUIBase";

const { ccclass, property, menu } = cc._decorator;

/** 公用UI管理方案类型 */
enum UIMgrType_T {
    NONE = 0,		// 默认
    POOL = 1 << 0,	// 启用对象池管理
    REMOVE = 1 << 1,	// 结束从父节点移除
    MUTI = 1 << 2,    // 允许UI同时创建多个
}

@ccclass
@menu('GlobalUI/GlobalUI')
export default class GlobalUI extends cc.Component {

    // global ui prefabs
    @property([cc.Prefab])
    private readonly pfbList: cc.Prefab[] = [];


    // 公共UI对象池列表
    private static _poolList: Map<number, cc.NodePool> = new Map();

    // LIFE-CYCLE CALLBACKS:

    onLoad() {
        // 注册常驻节点
        if (!cc.game.isPersistRootNode(this.node))
            cc.game.addPersistRootNode(this.node);

        for (let pfb of this.pfbList) {
            if (!pfb || !pfb.isValid) continue;
            switch (pfb.name) {
                // 全屏的LoadingUI
                case 'Loading':
                    GlobalUI.regPublicUI(pfb, yy.UIType.Loading, UIMgrType_T.POOL);
                    break;
                // 浮动框文字消息提示UI
                case 'Tips':
                    GlobalUI.regPublicUI(pfb, yy.UIType.User12, UIMgrType_T.POOL | UIMgrType_T.REMOVE | UIMgrType_T.MUTI);
                    break;
                // 快手奖励物品框
                case 'TipsRewards':
                    GlobalUI.regPublicUI(pfb, yy.UIType.User11, UIMgrType_T.POOL);
                    break;
                // 兑换界面
                case 'ExchangeView':
                    GlobalUI.regPublicUI(pfb, yy.UIType.User9, UIMgrType_T.POOL);
                    break;
                // 日志记录界面
                case 'LogRecordView':
                    GlobalUI.regPublicUI(pfb, yy.UIType.User8, UIMgrType_T.POOL);
                    break;
            }
        }
    }

    /**
     * 向yycore框架注册公用UI
     * @param pfb 预制体
     * @param uiType 注册公用UI类型
     * @param mgrType 公用UI管理方案类型
     */
    static regPublicUI(pfb: cc.Prefab, uiType: yy.UIType, mgrType: UIMgrType_T,
        initFunc?: (node: cc.Node, param?: yy.UIParam, subType?: any) => boolean) {
        yy.ui.manager.regPulibUI(uiType, (param?: yy.UIParam, subType?: any) => {
            if (!!param && !!param.isHide) {
                this.hideNode(uiType, mgrType);
            }
            else {
                const node: cc.Node = this.addNode(uiType, mgrType, pfb, param);
                if (!node || !node.isValid) return;
                if (!!initFunc && !initFunc(node, param, subType)) return;

                const comp: PublicUIBase = node.getComponent(PublicUIBase);
                if (!!comp) {
                    comp.endRemove = !!(mgrType & UIMgrType_T.REMOVE);
                    if (!!(mgrType & UIMgrType_T.POOL))
                        comp.nodePool = this.getPool(uiType);
                    comp.show(param);
                } else {
                    node.active = true;
                }
            }
        });
    }

    // 获取指定对象池
    private static getPool(uiType: yy.UIType): cc.NodePool {
        let pool: cc.NodePool = GlobalUI._poolList.get(uiType);
        if (!pool) {
            pool = new cc.NodePool();
            GlobalUI._poolList.set(uiType, pool);
        }
        return pool;
    }

    // 隐藏公用节点
    private static hideNode(uiType: yy.UIType, mType: UIMgrType_T): void {
        DebugExt.debug(`[GlobalUI] 隐藏 UIType.${yy.UIType[uiType]}`);

        const node: cc.Node = CanvasExt.getNode(uiType);
        if (!!node && node.isValid) {
            const comp: PublicUIBase = node.getComponent(PublicUIBase);
            if (!!comp) {
                comp.hide();
            } else {
                node.active = false;
                if (!!(mType & UIMgrType_T.POOL))
                    this.getPool(uiType).put(node);
            }
        }
    }

    private static addNode(uiType: yy.UIType, mType: UIMgrType_T, pfb: cc.Prefab, param?: yy.UIParam): cc.Node {
        DebugExt.debug(`[GlobalUI] 显示 UIType.${yy.UIType[uiType]}`);

        let node: cc.Node = null;
        let parent: cc.Node = !!param ? param.parentNode : null;
        if (!parent || !parent.isValid)
            parent = CanvasExt.canvasNode;

        if (!(mType & UIMgrType_T.MUTI)) {
            // 场景下只允许一个UI，从场景下获取节点
            node = CanvasExt.getNode(uiType, parent);
        }

        if ((!node || !node.isValid) && !!(mType & UIMgrType_T.POOL)) {
            // 指定对象池获取
            node = this.getPool(uiType).get();
            if (node)
                parent.addChild(node);
        }

        if ((!node || !node.isValid) && pfb)
            node = CanvasExt.addChild({
                node: pfb,
                uiType,
                parent
            });

        return node;
    }

}
